﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SqlMiM.Common.Model;
using System.Data.SqlClient;
using System.Data;
using SqlMiM.Common.Trace;
using System.Runtime.CompilerServices;

namespace SqlMiM.Common.Core
{
    public class ServerServices
    {
        #region Singleton

        private static ServerServices current;

        public static ServerServices Current
        {
            get
            {
                if (current == null)
                {
                    current = new ServerServices();
                }

                return current;
            }
        }

        #endregion

        private SqlCommand selectServerInfosCommand;

        internal Server GetServer(SqlConnection connection, bool throwException)
        {
            SqlDataReader reader = null;
            Server server = null;

            try
            {
                this.SelectServerInfosCommand.Connection = connection;

                connection.Open();

                reader = this.SelectServerInfosCommand.ExecuteReader();

                if (reader.HasRows)
                {
                    server = new Server();

                    while (reader.Read())
                    {
                        Server.FillFromReader(reader, server);
                    }
                }
                reader.Close();

                connection.Close();

            }
            catch (SqlException sqlEx)
            {
                if (throwException)
                    throw sqlEx;
                else
                    Notifier.Current.Notify(sqlEx);
            }
            catch (Exception ex)
            {
                if (throwException)
                    throw ex;
                else
                    Notifier.Current.Notify(ex);
            }
            finally
            {

                if (connection.State != ConnectionState.Closed)
                    connection.Close();

                if (reader != null)
                {
                    reader.Dispose();
                    reader = null;
                }

                if (connection != null)
                {
                    connection.Dispose();
                    connection = null;
                }
            }

            return server;
        }


        /// <summary>
        /// Get Server principals informations
        /// </summary>
        public Server GetServer()
        {
            SqlConnection connection = Context.Current.GetConnection();

            return this.GetServer(connection, false);
        }

        /// <summary>
        /// Get Command for Sql Server principals Informations
        /// </summary>
        public SqlCommand SelectServerInfosCommand
        {
            get
            {
                if (selectServerInfosCommand == null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("    SELECT SERVERPROPERTY(N'servername') as ServerName, CAST(case when 'a' <> 'A' then 1 else 0 end AS bit) AS [IsCaseSensitive], ");
                    sb.AppendLine("    CAST(FULLTEXTSERVICEPROPERTY('IsFullTextInstalled') AS bit) AS [IsFullTextInstalled], ");
                    sb.AppendLine("    @@MAX_PRECISION AS [MaxPrecision], ");
                    sb.AppendLine("    SERVERPROPERTY(N'ProductVersion') AS [VersionString], ");
                    sb.AppendLine("    CAST(SERVERPROPERTY(N'MachineName') AS sysname) AS [NetName], ");
                    sb.AppendLine("    CAST(SERVERPROPERTY(N'Edition') AS sysname) AS [Edition], ");
                    sb.AppendLine("    CAST(SERVERPROPERTY(N'ProductLevel') AS sysname) AS [ProductLevel], ");
                    sb.AppendLine("    CAST(SERVERPROPERTY('IsClustered') AS bit) AS [IsClustered], ");
                    sb.AppendLine("    CAST(SERVERPROPERTY('IsSingleUser') AS bit) AS [IsSingleUser], ");
                    sb.AppendLine("    CAST(SERVERPROPERTY('EngineEdition') AS int) AS [EngineEdition], ");
                    sb.AppendLine("    SERVERPROPERTY(N'ResourceVersion') AS [ResourceVersionString], ");
                    sb.AppendLine("    SERVERPROPERTY(N'ResourceLastUpdateDateTime') AS [ResourceLastUpdateDateTime], ");
                    sb.AppendLine("    SERVERPROPERTY(N'BuildClrVersion') AS [BuildClrVersionString], ");
                    sb.AppendLine("    SERVERPROPERTY(N'ComputerNamePhysicalNetBIOS') AS [ComputerNamePhysicalNetBIOS], ");
                    sb.AppendLine("    SERVERPROPERTY(N'CollationID') AS [CollationID], ");
                    sb.AppendLine("    SERVERPROPERTY(N'ComparisonStyle') AS [ComparisonStyle], ");
                    sb.AppendLine("    SERVERPROPERTY(N'SqlCharSet') AS [SqlCharSet], ");
                    sb.AppendLine("    SERVERPROPERTY(N'SqlCharSetName') AS [SqlCharSetName], ");
                    sb.AppendLine("    SERVERPROPERTY(N'SqlSortOrder') AS [SqlSortOrder], ");
                    sb.AppendLine("    SERVERPROPERTY(N'SqlSortOrderName') AS [SqlSortOrderName], ");
                    sb.AppendLine("    convert(sysname, serverproperty(N'collation')) AS [Collation] ");


                    selectServerInfosCommand = new SqlCommand();
                    selectServerInfosCommand.CommandType = CommandType.Text;
                    selectServerInfosCommand.CommandText = sb.ToString();

                }

                return selectServerInfosCommand;
            }
        }

    }
}
